﻿using System;
using System.Text;
using System.Drawing;
using System.Buffers;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;

public static partial class glDRIVE
{
    /*
    函数 gl.muav
    实矩阵的奇异值分解
    参数 a: a[m][n]存放m×n的实矩阵A。返回时其对角线给出奇异值（以非递增次序排列），其余元素均为0。
    参数 m: 
    参数 n: 
    参数 u: u[m][m]返回左奇异向量U。
    参数 v: v[n][n]返回右奇异向量VT 。
    参数 eps: 给定的精度要求。
    参数 ka: 其值为max(m，n)＋1。
    参数 inter: 最多迭代次数，60
    返回值 若小于0，则表示失败；若大于0，则表示正常。
    */

    public static string drive_muav()
    {
        int i, j;
        double[,] a = new double[4, 3] {
            {1.0,1.0,-1.0},
            {2.0,1.0,0.0},
            {1.0,-1.0,0.0},
            {-1.0,2.0,1.0}
        };
        double[,] b = new double[3, 4] {
            {1.0,1.0,-1.0,-1.0},
            {2.0,1.0, 0.0,2.0},
            {1.0,-1.0,0.0,1.0}
        };
        double[,] u = new double[4, 4];
        double[,] v = new double[3, 3];
        double[,] c = new double[4, 3];
        double[,] d = new double[3, 4];

        int m = 4;
        int n = 3;
        int ka = Math.Max(m, n) + 1;
        double eps = 0.000001;

        string rs = gl.html_table("矩阵 A:", a);
        i = gl.muav(a, m, n, u, v, eps, ka, 60);
        if (i < 0) return "error: 0";
        rs += gl.html_table("矩阵 U:", u);
        rs += gl.html_table("矩阵 V:", v);
        rs += gl.html_table("矩阵 A:", a);
        gl.tmul(u, m, m, a, m, n, c);
        rs += gl.html_table("矩阵 C=UA:", c);
        gl.tmul(c, m, n, v, n, n, a);
        rs += gl.html_table("矩阵 A=UAV:", a);

        rs += gl.html_table("验证 矩阵 B:", b);
        i = gl.muav(b, n, m, v, u, eps, ka, 60);
        if (i < 0) return "error: 0";
        rs += gl.html_table("矩阵 U:", u);
        rs += gl.html_table("矩阵 V:", v);
        rs += gl.html_table("矩阵 B:", b);
        gl.tmul(v, n, n, b, n, m, d);
        rs += gl.html_table("矩阵 D=UB:", c);
        gl.tmul(d, n, m, u, m, m, b);
        rs += gl.html_table("矩阵 UBV:", b);

        return rs;
    }
}